import tkinter as tk
from tkinter import ttk,Text
from tkinter import messagebox
from datetime import datetime
from tkcalendar import DateEntry
import pandas as pd
from setting import Setting

from reportlab.lib import colors
from reportlab.lib.pagesizes import A4, letter
from reportlab.pdfgen import canvas
from reportlab.platypus import Table, TableStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

class Receipt:
    def __init__(self):
        self.setting = Setting()
        self.url_fileRoomInfo = self.setting.url_fileRoomInfo
        self.url_fileTenantInfo = self.setting.url_fileTenantInfo
        self.url_fileRentalInfo = self.setting.url_fileRentalInfo
        # 注册中文字体，这里以宋体为例
        pdfmetrics.registerFont(TTFont("SimHei", "SimHei.ttf"))

    def receiptManger(self, frame4):#收据管理
        """设置布局"""
        canvas = tk.Canvas(frame4, width=500, height=300)
        canvas.pack(side=tk.TOP)
        canvas1 = tk.Canvas(frame4, width=500, height=10, bg="blue")#, bg="blue"
        canvas1.pack()
        self.canvas2 = tk.Canvas(frame4, width=500, height=400)#, bg="red"
        self.canvas2.pack()#side=tk.BOTTOM

        """设置查询管理"""
        LabelTitler = ttk.Label(canvas, text="收租期间", relief="solid", padding=(4, 4), width=10,
                                font=("微软雅黑", 10, "bold"), anchor="center")
        LabelTitler.grid(row=0, column=0)
        # self.enTmonth = ttk.Entry(canvas1, width=12)
        # self.enTmonth.grid(row=1, column=0, sticky='nsew')
        self.enTmonth = ttk.Combobox(canvas, width=9)
        self.enTmonth['values'] = self.setting.monthList()  # 赋值列表
        self.enTmonth.grid(row=1, column=0, sticky='nsew')
        LabelTitler = ttk.Label(canvas, text="房间号", relief="solid", padding=(4, 4), width=10,
                                font=("微软雅黑", 10, "bold"), anchor="center")
        LabelTitler.grid(row=0, column=1)
        self.enTroomid = ttk.Combobox(canvas, width=9)
        self.enTroomid['values'] = self.setting.roomList(self.url_fileTenantInfo, 'Tenant')  # 赋值列表
        self.enTroomid.grid(row=1, column=1, sticky='nsew')

        hpBtn1 = ttk.Button(canvas, text="收据生成", command=self.creatReceipt)
        hpBtn1.grid(row=2, column=0,columnspan=1, sticky='nsew')

        hpBtn2 = ttk.Button(canvas, text="打印", command=self.printReceipt)
        hpBtn2.grid(row=2, column=1,columnspan=1, sticky='nsew')
        hpBtn3 = ttk.Button(canvas, text="打印(按月)", command=self.printReceiptMonth)
        hpBtn3.grid(row=2, column=2,columnspan=1, sticky='nsew')

        self.showReceipt()

    def showReceipt(self):
        # 标题
        LabelTitler = ttk.Label(self.canvas2, text="水电费收据", relief="solid", padding=(2, 2), width=10, font=("微软雅黑", 14, "bold"), anchor="center")
        LabelTitler.grid(row=0, column=0,columnspan=9, sticky='nsew')
        # 第一行
        rowNum = 1
        LabelInner10 = ttk.Label(self.canvas2, text="客户：", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner10.grid(row=rowNum, column=0, sticky='nsew')
        self.LabelInner11 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        self.LabelInner11.grid(row=rowNum, column=1, sticky='nsew')
        LabelInner12 = ttk.Label(self.canvas2, text="计费周期：", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner12.grid(row=rowNum, column=2,columnspan=1, sticky='nsew')
        LabelInner13 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner13.grid(row=rowNum, column=3,columnspan=2, sticky='nsew')
        LabelInner14 = ttk.Label(self.canvas2, text="收款日期：", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner14.grid(row=rowNum, column=5,columnspan=1, sticky='nsew')
        LabelInner15 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner15.grid(row=rowNum, column=6,columnspan=1, sticky='nsew')
        # 第二行
        rowNum = 2
        LabelInner20 = ttk.Label(self.canvas2, text="品名", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner20.grid(row=rowNum, column=0, sticky='nsew')
        LabelInner21 = ttk.Label(self.canvas2, text="上月读数", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner21.grid(row=rowNum, column=1, sticky='nsew')
        LabelInner22 = ttk.Label(self.canvas2, text="本月读数", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner22.grid(row=rowNum, column=2, columnspan=1, sticky='nsew')
        LabelInner23 = ttk.Label(self.canvas2, text="单位", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner23.grid(row=rowNum, column=3, columnspan=1, sticky='nsew')
        LabelInner24 = ttk.Label(self.canvas2, text="数量", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner24.grid(row=rowNum, column=4, columnspan=1, sticky='nsew')
        LabelInner25 = ttk.Label(self.canvas2, text="单价（元）", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner25.grid(row=rowNum, column=5, columnspan=1, sticky='nsew')
        LabelInner26 = ttk.Label(self.canvas2, text="金额（元）", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner26.grid(row=rowNum, column=6, columnspan=1, sticky='nsew')
        # 第三行
        rowNum = 3
        LabelInner30 = ttk.Label(self.canvas2, text="水费", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner30.grid(row=rowNum, column=0, sticky='nsew')
        self.LabelInner31 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        self.LabelInner31.grid(row=rowNum, column=1, sticky='nsew')
        self.LabelInner32 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        self.LabelInner32.grid(row=rowNum, column=2,columnspan=1, sticky='nsew')
        LabelInner33 = ttk.Label(self.canvas2, text="吨", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner33.grid(row=rowNum, column=3,columnspan=1, sticky='nsew')
        self.LabelInner34 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        self.LabelInner34.grid(row=rowNum, column=4,columnspan=1, sticky='nsew')
        self.LabelInner35 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        self.LabelInner35.grid(row=rowNum, column=5,columnspan=1, sticky='nsew')
        self.LabelInner36 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        self.LabelInner36.grid(row=rowNum, column=6,columnspan=1, sticky='nsew')
        # 第四行
        rowNum = 4
        LabelInner40 = ttk.Label(self.canvas2, text="电费", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner40.grid(row=rowNum, column=0, sticky='nsew')
        self.LabelInner41 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        self.LabelInner41.grid(row=rowNum, column=1, sticky='nsew')
        self.LabelInner42 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        self.LabelInner42.grid(row=rowNum, column=2,columnspan=1, sticky='nsew')
        LabelInner43 = ttk.Label(self.canvas2, text="度", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner43.grid(row=rowNum, column=3,columnspan=1, sticky='nsew')
        self.LabelInner44 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        self.LabelInner44.grid(row=rowNum, column=4,columnspan=1, sticky='nsew')
        self.LabelInner45 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        self.LabelInner45.grid(row=rowNum, column=5,columnspan=1, sticky='nsew')
        self.LabelInner46 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        self.LabelInner46.grid(row=rowNum, column=6,columnspan=1, sticky='nsew')
        # 第五行
        rowNum = 5
        LabelInner50 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner50.grid(row=rowNum, column=0, sticky='nsew')
        LabelInner51 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner51.grid(row=rowNum, column=1, sticky='nsew')
        LabelInner52 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner52.grid(row=rowNum, column=2,columnspan=1, sticky='nsew')
        LabelInner53 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner53.grid(row=rowNum, column=3,columnspan=1, sticky='nsew')
        LabelInner54 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner54.grid(row=rowNum, column=4,columnspan=1, sticky='nsew')
        LabelInner55 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner55.grid(row=rowNum, column=5,columnspan=1, sticky='nsew')
        LabelInner56 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner56.grid(row=rowNum, column=6,columnspan=1, sticky='nsew')
        # 第六行
        rowNum = 6
        LabelInner60 = ttk.Label(self.canvas2, text="合计金额：", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner60.grid(row=rowNum, column=0, sticky='nsew')
        self.LabelInner61 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        self.LabelInner61.grid(row=rowNum, column=1,columnspan=3, sticky='nsew')
        self.LabelInner62 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        self.LabelInner62.grid(row=rowNum, column=4,columnspan=3, sticky='nsew')
        # 第七行
        rowNum = 7
        LabelInner70 = ttk.Label(self.canvas2, text="收款人：", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="e")
        LabelInner70.grid(row=rowNum, column=0, columnspan=6, sticky='nsew')
        LabelInner71 = ttk.Label(self.canvas2, text="", relief="solid", padding=(4, 4), width=10, font=("微软雅黑", 10), anchor="center")
        LabelInner71.grid(row=rowNum, column=6, columnspan=1, sticky='nsew')

        #LabelInner71.config(text= '测试')

    def creatReceipt(self):
        month = self.enTmonth.get()
        roomid = self.enTroomid.get()
        # 如果没有输入收租期间或房间号则提示且退出
        if month == '' or roomid == '':
            messagebox.showwarning("提示", "请输入'收租期间'和'房间号'！")
            return

        df = pd.read_excel(self.url_fileRentalInfo, sheet_name='Rental', engine='openpyxl', header=0)
        # 构造时间+房间的查询条件
        f_month = df['month'] == int(month)
        f_roomid = df['roomid'] == roomid
        #print(f_month)
        #print(f_roomid)
        try:
            # 定义条件
            row_index = df.index[f_month & f_roomid].tolist()[0]  # 获取需要删除房间索引
            name = df.loc[row_index, 'name']
            rentaltime = df.loc[row_index, 'rentaltime']
            warter1 = df.loc[row_index, 'warter1']
            warter2 = df.loc[row_index, 'warter2']
            electric1 = df.loc[row_index, 'electric1']
            electric2 = df.loc[row_index, 'electric2']
            amount = df.loc[row_index, 'amount']
            warter1last = df.loc[row_index, 'warter1last']
            warter2last = df.loc[row_index, 'warter2last']
            electric1last = df.loc[row_index, 'electric1last']
            electric2last = df.loc[row_index, 'electric2last']

            # 获取水电单价
            warterPrice = self.setting.get_warterPrice()
            electricPrice = self.setting.get_electricPrice()

            warter1Sum = warter1 - warter1last
            warter2Sum = warter2 - warter2last

            electric1Sum = electric1 - electric1last
            electric2Sum = electric2 - electric2last

            warterAmount = warter1Sum * warterPrice
            electricAmount = electric1Sum * electricPrice
            self.LabelInner11.config(text=roomid) #客户

            self.LabelInner31.config(text = warter1last) #上月水表读数
            self.LabelInner32.config(text = warter1) #本月水表读数
            self.LabelInner34.config(text = warter1Sum)
            self.LabelInner35.config(text = warterPrice)
            self.LabelInner36.config(text = warterAmount)

            self.LabelInner41.config(text = warter1last) #上月电表读数
            self.LabelInner42.config(text = warter1) #本月电表读数
            self.LabelInner44.config(text = electric1Sum)
            self.LabelInner45.config(text = electricPrice)
            self.LabelInner46.config(text = electricAmount)

            self.LabelInner62.config(text = (warterAmount + electricAmount))
            number = warterAmount + electricAmount
            chinese_amount = self.setting.number_to_chinese(number)
            #print(chinese_amount)  # 输出: 陆佰肆拾捌元整
            self.LabelInner61.config(text = chinese_amount)

        except Exception as e:
            messagebox.showwarning("提示", f"发生了一个错误：{e}")
            print(f"发生了一个错误：{e}")

    def printReceipt(self):

        # 准备一个8*7的表
        table_data = [
            ["水电费收据", "", "", "", "", "", ""],
            ["客户：", self.LabelInner11.cget("text"), "计费周期：", "", "", "收款日期：", ""],
            ["品名", "上月读数", "本月读数", "  单位  ", "  数量  ", "单价（元）", "金额（元）"],
            ["水费", self.LabelInner31.cget("text"), self.LabelInner32.cget("text"), "吨", self.LabelInner34.cget("text"), self.LabelInner35.cget("text"), self.LabelInner36.cget("text")],
            ["电费", self.LabelInner41.cget("text"), self.LabelInner42.cget("text"), "度", self.LabelInner44.cget("text"), self.LabelInner45.cget("text"), self.LabelInner46.cget("text")],
            ["", "", "", "", "", "", ""],
            ["合计金额：", self.LabelInner61.cget("text"), "", "", self.LabelInner62.cget("text"), "", ""],
            ["收款人：", "", "", "", "", "", ""]
        ]

        # 设置每列的宽度
        row_heights = [30, 22, 22, 22, 22, 22, 22, 22]

        # 创建表格
        t = Table(table_data,  rowHeights=row_heights)

        # 定义表格样式
        table_style = TableStyle([
            # 为整个表格设置默认样式
            ('ROWHEIGHTS', (0, 0), (-1, -1), 30), #设置行高
            ('GRID', (0, 0), (-1, -1), 1, colors.black),
            ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),   # 水平居中
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 垂直居中 VALIGN参数可以设置垂直对齐方式，其值可以是'TOP'、'MIDDLE'或'BOTTOM'
            ('ALIGN', (0, 7), (0, 7), 'RIGHT'),
            ('FONTNAME', (0, 0), (-1, -1), 'SimHei'),
            ('FONTSIZE', (0, 0), (-1, -1), 12),
            # 为表头设置样式
            ('FONTSIZE', (0, 0), (0, 0), 16),
            # 合并单元格
            ('SPAN', (0, 0), (6, 0)),  # 合并第一行第一列到第七列
            ('SPAN', (3, 1), (4, 1)),  # 合并第一行第二列到第三列
            ('SPAN', (1, 6), (3, 6)),  # 合并第一行第二列到第三列
            ('SPAN', (4, 6), (6, 6)),  # 合并第一行第二列到第三列
            ('SPAN', (0, 7), (5, 7))  # 合并第一行第二列到第三列
        ])

        # 应用样式到表格
        t.setStyle(table_style)

        # 创建PDF对象
        pdf_filename = 'data/my_pdf_document_with_table.pdf'
        # 创建一个canvas对象，用于绘制PDF
        c = canvas.Canvas(pdf_filename, pagesize=A4)

        # 计算表格需要的宽度和高度
        table_width, table_height = t.wrap(0, 0)

        x = (letter[0] - table_width) / 2
        y = (letter[1] - table_height)
        # 在页面上添加表格
        t.wrapOn(c, x, y)  # 计算表格所需宽度
        t.drawOn(c, x, y)  # 绘制表格
        #c.showPage() # 结束当前页面并开始新页面
        # 保存PDF
        c.save()
        messagebox.showwarning("提示", "打印成功！")

    def printReceiptMonth(self):

        # 获取水电单价
        warterPrice = self.setting.get_warterPrice()
        electricPrice = self.setting.get_electricPrice()

        month = self.enTmonth.get()
        # 如果没有输入收租期间或房间号则提示且退出
        if month == '':
            messagebox.showwarning("提示", "请输入'收租期间'！")
            return

        df = pd.read_excel(self.url_fileRentalInfo, sheet_name='Rental', engine='openpyxl', header=0)
        # 构造查询条件
        f_month = df['month'] == int(month)
        try:
            # 创建PDF对象
            pdf_filename = 'data/my_pdf_document_with_table_month.pdf'
            # 创建一个canvas对象，用于绘制PDF
            c = canvas.Canvas(pdf_filename, pagesize=A4)

            # 定义表格样式
            table_style = TableStyle([
                # 为整个表格设置默认样式
                ('ROWHEIGHTS', (0, 0), (-1, -1), 30),  # 设置行高
                ('GRID', (0, 0), (-1, -1), 1, colors.black),
                ('TEXTCOLOR', (0, 0), (-1, -1), colors.black),
                ('ALIGN', (0, 0), (-1, -1), 'CENTER'),  # 水平居中
                ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 垂直居中 VALIGN参数可以设置垂直对齐方式，其值可以是'TOP'、'MIDDLE'或'BOTTOM'
                ('ALIGN', (0, 7), (0, 7), 'RIGHT'),
                ('FONTNAME', (0, 0), (-1, -1), 'SimHei'),
                ('FONTSIZE', (0, 0), (-1, -1), 12),
                # 为表头设置样式
                ('FONTSIZE', (0, 0), (0, 0), 16),
                # 合并单元格
                ('SPAN', (0, 0), (6, 0)),  # 合并第一行第一列到第七列
                ('SPAN', (3, 1), (4, 1)),  # 合并第一行第二列到第三列
                ('SPAN', (1, 6), (3, 6)),  # 合并第一行第二列到第三列
                ('SPAN', (4, 6), (6, 6)),  # 合并第一行第二列到第三列
                ('SPAN', (0, 7), (5, 7))  # 合并第一行第二列到第三列
            ])

            # 定义条件
            row_indexList = df.index[f_month].tolist()  # 获取需要删除房间索引
            tableNum = 1
            for row_index in row_indexList:
                roomId = df.loc[row_index, 'roomid']
                rentaltime = df.loc[row_index, 'rentaltime']
                warter1 = df.loc[row_index, 'warter1']
                warter2 = df.loc[row_index, 'warter2']
                electric1 = df.loc[row_index, 'electric1']
                electric2 = df.loc[row_index, 'electric2']
                amount = df.loc[row_index, 'amount']
                warter1last = df.loc[row_index, 'warter1last']
                warter2last = df.loc[row_index, 'warter2last']
                electric1last = df.loc[row_index, 'electric1last']
                electric2last = df.loc[row_index, 'electric2last']

                warter1Sum = warter1 - warter1last
                warter2Sum = warter2 - warter2last

                electric1Sum = electric1 - electric1last
                electric2Sum = electric2 - electric2last

                warterAmount = warter1Sum * warterPrice
                electricAmount = electric1Sum * electricPrice

                number = warterAmount + electricAmount
                chinese_amount = self.setting.number_to_chinese(number)
                # print(chinese_amount)  # 输出: 陆佰肆拾捌元整

                # 准备一个8*7的表
                table_data = [
                    ["水电费收据", "", "", "", "", "", ""],
                    ["客户：", roomId, "计费周期：", "", "", "收款日期：", ""],
                    ["品名", "上月读数", "本月读数", "  单位  ", "  数量  ", "单价（元）", "金额（元）"],
                    ["水费", warter1last, warter1, "吨", warter1Sum, warterPrice, warterAmount],
                    ["电费", electric1last, electric1, "度", electric1Sum, electricPrice, electricAmount],
                    ["", "", "", "", "", "", ""],
                    ["合计金额：", chinese_amount, "", "", number, "", ""],
                    ["收款人：", "", "", "", "", "", ""]
                ]

                # 设置每列的宽度
                row_heights = [30, 22, 22, 22, 22, 22, 22, 22]

                # 创建表格
                t = Table(table_data, rowHeights=row_heights)

                # 应用样式到表格
                t.setStyle(table_style)

                # 计算表格需要的宽度和高度
                table_width, table_height = t.wrap(0, 0)
                x = (letter[0] - table_width) / 2
                y = (letter[1] - tableNum*(table_height + 5.0))
                # 在页面上添加表格
                t.wrapOn(c, x, y)  # 计算表格所需宽度
                t.drawOn(c, x, y)  # 绘制表格

                tableNum = tableNum + 1
                #如果下一个表格超出当前PDF页面则新开一页
                if (letter[1] - tableNum*(table_height + 5.0)) <=0 :
                    c.showPage() # 结束当前页面并开始新页面
                    tableNum = 1

            #结束for循环
            # 保存PDF
            c.save()
            messagebox.showwarning("提示", "打印成功！")

        except Exception as e:
            messagebox.showwarning("提示", f"发生了一个错误：{e}")
            print(f"发生了一个错误：{e}")